﻿using Lib.WPF.Core;
using Lib.WPF.Entitys;
using Lib.WPF.Views;
using System.Diagnostics;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;

namespace Lib.WPF.ViewModels;
/// <summary>
/// 主程序视图模型
/// </summary>
public class Main : ViewModelBase {
    /// <summary>
    /// 构造函数
    /// </summary>
    public Main() {
        //
        var Key = "AppSettings";
        //
        if (Session.ContainsKey(Key)) {
            this.Configs = Session.Get<Configs>(Key);
        }
        //
        Key = "LoginConfigs";
        //
        if (Session.ContainsKey(Key)) {
            this.LoginConfigs = Session.Get<LoginConfigs>(Key);
        } else {
            this.LoginConfigs = new();
        }
        //
        Key = "LoginEntity";
        //
        if (Session.ContainsKey(Key)) {
            this.LoginEntity = Session.Get<LoginEntity>(Key);
        } else {
            this.LoginEntity = new();
        }
        //
        this.LoginName = this.LoginConfigs?.LoginName;
        //
        this.IsAutoLogon = this.LoginConfigs.IsAutoLogon;
        //
        this.IsCloseMinTray = this.LoginConfigs.IsCloseMinTray;
        //
        if (Debugger.IsAttached) {
            //
            this.IsBinary = false;
            //
            this.SecretKey = null;
        } else {
            //
            this.IsBinary = true;
            //
            this.SecretKey = this.Configs.SecretKey;
        }
        //
        this.InitCommand();
        //
        this.Window.SizeChanged += (Sender, e) => {
            if (LoadComplete) {
                this.InitTabsCanvas();
            }
        };

    }

    /// <summary>
    /// 初始化（Window.Loaded += Initialize）
    /// </summary>
    public override void Initialize() {

        try {
            this.Min = GetResource<double>("Theme.West.Min");
            this.Size = GetResource<GridLength>("Theme.West.Size");
        } catch {
            this.Min = 180;
            this.Size = new GridLength(200);
        }
 
        this.Expansion = Visibility.Visible;

        if (Pages.TryGetValue("Home", out Page Home)) {
          
        } else {
            Pages.Add("Home", Home = PageEmpty.Create());
        }

        this.CurrentPage = Home;

        this.Panel = Find<StackPanel>("Panel");

        this.Tabs = Find<StackPanel>("Tabs");

        this.Canvas = Find<Canvas>("Canvas");

        this.RadioKeys = [];

        this.Navigation = [];

        try {
            //
            var Resources = Common.GetFile<List<Navigate>>("Resources.json");
            //
            if (Resources.Count > 0) {
                InitNavigates(Resources);
            }
        } catch (Exception ex) {
            MessageBox.Show($"导航菜单初始化出错！\n\n错误信息：{ex.Message}");
        }

    }
    /// <summary>
    /// 
    /// </summary>
    private void InitCommand() {
        //
        this.CMD = new Command(P => {
            if (P != null) {
                var arrKeys = P?.ToString().Split('.');
                var Key = arrKeys[0];
                var Value = string.Empty;
                if (arrKeys.Length == 2) {
                    Value = arrKeys[1];
                } else {
                    Value = null;
                }
                try {
                    switch (Key) {
                        case "Page":
                            Create(Value);
                            break;
                        case "Tabs":
                            Active(Value);
                            break;
                        case "Close":
                            Close(Value);
                            break;
                        case "Toggle":
                            Toggle();
                            break;
                        case "Front":
                            Move(Key);
                            break;
                        case "Back":
                            Move(Key);
                            break;
                        case "Renovate":
                            break;
                        case "ShowWindow":
                            ShowWindow();
                            break;
                        case "IsAutoLogon":
                            this.LoginConfigs.IsAutoLogon = this.IsAutoLogon;
                            Common.SaveFile<LoginConfigs>(this.LoginConfigs, "LoginConfigs.json", this.IsBinary, this.SecretKey);
                            break;
                        case "IsCloseMinTray":
                            this.LoginConfigs.IsCloseMinTray = this.IsCloseMinTray;
                            Common.SaveFile<LoginConfigs>(this.LoginConfigs, "LoginConfigs.json", this.IsBinary, this.SecretKey);
                            break;
                        case "Shutdown":
                            Main.ApplicationClosing = true;
                            Application.Current.Shutdown();
                            break;
                        default:
                            MessageBox.Show($"命令“{Key}”还在开发中！");
                            break;
                    }
                } catch (Exception ex) {
                    MessageBox.Show($"执行“{Key}”命令出错！\n\n相关参数：{Value}\n\n错误信息：{ex.Message}");
                }
            }
        });
    }

    /// <summary>
    /// 
    /// </summary>
    private void InitTabsCanvas() {
        var CW = this.Canvas.ActualWidth;
        var TW = this.Tabs.ActualWidth;
        if (CW >= TW) {
            this.CanvasLeft = 0;
        } else {
            if ((TW + this.CanvasLeft) < CW) {
                this.CanvasLeft = Convert.ToInt32(CW - TW);
            }
        }
    }
    /// <summary>
    /// 
    /// </summary>
    private void Move(string Key) {
        var CW = this.Canvas.ActualWidth;
        var TW = this.Tabs.ActualWidth;
        switch (Key) {
            case "Front":
                if(CW >= TW) {
                    this.CanvasLeft = 0;
                } else {
                    if ((TW + this.CanvasLeft - 30) < CW) {
                        this.CanvasLeft = Convert.ToInt32(CW - TW);
                    } else {
                        this.CanvasLeft -= 30;
                    }
                }
                break;
            case "Back":
                if (CW >= TW) {
                    this.CanvasLeft = 0;
                } else {
                    if((this.CanvasLeft + 30) > 0) {
                        this.CanvasLeft = 0;
                    } else {
                        this.CanvasLeft += 30;
                    }
                }
                break;
            default:
                break;
        }
    }
    /// <summary>
    /// 创建指定标识符的 Page 元素对象
    /// </summary>
    private void Create(string Key) {

        var IsContinue = false;

        if (Navigation.TryGetValue(Key, out Navigate Rs)) {
            IsContinue = true;
        }
        if (Pages.TryGetValue(Key, out Page Page)) {

        } else {
            if (IsContinue) {
                Page = PageEmpty.Create($"“{Rs.Title}”模块正在实现中...");  
            } else {
                Page = PageEmpty.Create();
            }
            Pages.Add(Rs.Key, Page);
        }
        if (IsContinue) {
            try {
                var Tab = this.Tabs.FindName(Rs.Tab.Name);
                if (Tab == null) {
                    Rs.Tab.Index = this.Index;
                    this.Index += 1;
                    this.Tabs.Children.Add(Rs.Tab.Control); 
                    this.Tabs.RegisterName(Rs.Tab.Name, Rs.Tab.Control);
                }
                Rs.Tab.Control.IsChecked = true; 
            } catch(Exception ex) {
                MessageBox.Show($"导航菜单标签生成出错！\n\n错误信息：{ex.Message}");
            }
        }
        if (Page != null) {
            CurrentPage = Page;
        }
    }
    /// <summary>
    /// 设为当前页
    /// </summary>
    private void Active(string Key) {
        if (Pages.TryGetValue(Key, out Page Value) && CurrentPage != Value) {
            CurrentPage = Value;
        }
    }
    /// <summary>
    /// 关闭页面
    /// </summary>
    /// <param name="Key"></param>
    private void Close(string Key) {
        var Count = this.Tabs.Children.Count;
        var List = new List<RadioButton>();
        var Index = 0;
        RadioButton Radio = null;
        if(this.SelectedTab != null) {
            Radio = this.SelectedTab;
        }
        switch (Key) {
            case "This":
                if(Count > 0) {
                    if (Radio != null) {
                        Index = RadioKeys[Radio].Index;
                        List.Add(Radio);
                     } else {
                        foreach (RadioButton Re in this.Tabs.Children) {
                            if (Re.IsChecked.Value) {
                                Radio = Re;
                                Index = RadioKeys[Re].Index;
                                List.Add(Re);
                                break;
                            }
                        }
                    }
                }
                break;
            case "All":
                if (Count > 0) {
                    foreach (RadioButton Re in this.Tabs.Children) {
                        List.Add(Re);
                    }
                }
                break;
            case "Siblings":
                if (Count > 0) {
                    if (Radio != null) {
                        foreach (RadioButton Re in this.Tabs.Children) {
                            if (Re != Radio) {
                                List.Add(Re);
                            }
                        }
                    } else {
                        foreach (RadioButton Re in this.Tabs.Children) {
                            if (Re.IsChecked.Value) {
                                Radio = Re;
                            } else {
                                List.Add(Re);
                            }
                        }
                    }
                }
                break;
            case "Front":
                if (Count > 0) {
                    if (Radio != null) {
                        foreach (RadioButton Re in this.Tabs.Children) {
                            if (Re == Radio) {
                                break;
                            } else {
                                List.Add(Re);
                            }
                        }
                    } else {
                        foreach (RadioButton Re in this.Tabs.Children) {
                            if (Re.IsChecked.Value) {
                                Radio = Re;
                                break;
                            } else {
                                List.Add(Re);
                            }
                        }
                    }
                }
                break;
            case "Back":
                var Begin = false;
                if (Count > 0) {
                    if (Radio != null) {
                        foreach (RadioButton Re in this.Tabs.Children) {
                            if (Re == Radio) {
                                Begin = true;
                            } else {
                                if (Begin) {
                                    List.Add(Re);
                                }
                            }
                        }
                    } else {
                        foreach (RadioButton Re in this.Tabs.Children) {
                            if (Re.IsChecked.Value) {
                                Radio = Re; Begin = true;
                            } else {
                                if (Begin) {
                                    List.Add(Re);
                                }
                            }
                        }
                    }
                }
                break;
            default:
                if(Navigation.TryGetValue(Key, out Navigate Rs)) {
                    Radio = Rs.Tab.Control;
                    Index = Rs.Tab.Index;
                    List.Add(Rs.Tab.Control); 
                }
                break;
        }
        var IsContinue = false;
        if (List.Count > 0) {
            foreach (RadioButton Re in List) {
                var Tab = RadioKeys[Re];
                if(Tab.Key == "Home" || Tab.IsLock) {
                    continue;
                }
                this.Tabs.Children.Remove(Re);
                this.Tabs.UnregisterName(Tab.Name);
                Re.IsChecked = false;
                Tab.Index = 0;
                if (Pages.ContainsKey(Tab.Key)) {
                    Pages.Remove(Tab.Key);
                }
            }
            IsContinue = true; List.Clear();
        }
        var PageKey = "Home";
        if (IsContinue) {
            IsContinue = false;
            Count = this.Tabs.Children.Count;
            if (Count > 0) {
                if(Radio != null) {
                    if (Radio.IsChecked.Value) {

                    } else {
                        IsContinue = true;
                        if(Index > Count) {
                            Radio = (RadioButton)this.Tabs.Children[Count - 1];
                        } else {
                            if(Index <= 0) {
                                Index = 0;
                            } else {
                                Index -= 1;
                            }
                            Radio = (RadioButton)this.Tabs.Children[Index];
                        }
                    }
                } else {
                    IsContinue = true;
                    Radio = (RadioButton)this.Tabs.Children[0];
                }
                if (IsContinue) {
                    Radio.IsChecked = true;
                    PageKey = RadioKeys[Radio].Key;
                }
            }
        }
        this.SelectedTab = null;
        if (IsContinue && Pages.TryGetValue(PageKey, out Page Value)) {
            CurrentPage = Value;
        }
        InitTabSort();
    }
    /// <summary>
    /// 
    /// </summary>
    private void InitTabSort() {
        var Index = 0;
        if(this.Tabs.Children.Count > 0) {
            foreach (RadioButton Re in this.Tabs.Children) {
                RadioKeys[Re].Index = Index; Index += 1;
            }
        }
        this.Index = Index;
    }
    /// <summary>
    /// 初始化侧边菜单
    /// </summary>
    private void InitNavigates(List<Navigate> List, StackPanel Panel = null) {

        Panel ??= this.Panel;

        if(List != null && List.Count > 0) {
            foreach (var Rs in List) {
                if (string.IsNullOrEmpty(Rs.Key)) {
                    Rs.Key = Guid.NewGuid().ToString().Replace("-", "").ToUpper();
                }
                if (string.IsNullOrEmpty(Rs.Picture)) {
                    if (Rs.Children.Count > 0) {
                        Rs.Picture = "\uE802";
                    } else {
                        Rs.Picture = "\uEA6D";
                    }
                }
                Navigation.Add(Rs.Key, Rs);
                if (Rs.Children.Count > 0) {
                    var Stack = new StackPanel();
                    var Expander = new Expander() {
                        Header = Rs.Title,
                        IsExpanded = Rs.Expanded,
                        Tag = Rs.Picture,
                        Content = Stack,
                        Style = GetResource<Style>("Side.Expander")
                    };
                    Panel.Children.Add(Expander);
                    InitNavigates(Rs.Children, Stack);
                } else {
                    // 侧边导航按钮
                    var Radio = new RadioButton() {
                        Content = Rs.Title,
                        GroupName = "Side",
                        Style = GetResource<Style>("Side.Navigate"),
                        Tag = Rs.Picture,
                        Command = CMD,
                        CommandParameter = $"Page.{Rs.Key}"
                    };
                    Rs.Control = Radio;
                    Panel.Children.Add(Radio);
                    // 标签实体类
                    Rs.Tab = Tab.Create(Rs.Key, Rs.Title);
                    Rs.Tab.Name = $"Tabs_{Rs.Key}";
                    // 标签按钮控件
                    Rs.Tab.Control = new RadioButton() {
                        Name = Rs.Tab.Name,
                        Content = Rs.Title,
                        GroupName = "Tabs",
                        Style = GetResource<Style>("Side.Tabs"),
                        Tag=Rs.Picture,
                        Command = CMD,
                        CommandParameter = $"Tabs.{Rs.Key}"
                    };
                    Rs.Tab.Control.InputBindings.Add(new MouseBinding() {
                        MouseAction = MouseAction.LeftDoubleClick,
                        Command = CMD,
                        CommandParameter = $"Close.{Rs.Key}"
                    });
                    Rs.Tab.Control.SetValue(Dependents.Defaults.KeyProperty, Rs.Key);
                    Rs.Tab.Control.SetValue(Dependents.Defaults.CommandProperty, CMD);
                    Rs.Tab.Control.SetValue(Dependents.Defaults.ValueProperty, $"Close.{Rs.Key}");
                    RadioKeys.Add(Rs.Tab.Control, Rs.Tab);
                }
            }
        }
        
    }
    /// <summary>
    /// 
    /// </summary>
    private readonly double MinWidth = GetResource<double>("Theme.West.Min");
    /// <summary>
    /// 侧边栏伸缩
    /// </summary>
    private void Toggle() {
        try {
            if (this.Expansion != Visibility.Visible) {
                this.Expansion = Visibility.Visible;
                this.Min = MinWidth;
                this.Size = GetHistory<GridLength>("Size");
            } else {
                this.Expansion = Visibility.Collapsed;
                this.Min = 0;
                this.Size = new GridLength(0, GridUnitType.Star); 
            }
        } catch (Exception e) {
            MessageBox.Show($"错误：{e.Message}");
        }
        this.InitTabsCanvas();
    }
    /// <summary>
    /// 显示主窗体
    /// </summary>
    public static void ShowWindow() {
        var Window = Application.Current.MainWindow;
        if (Window.WindowState == WindowState.Minimized) {
            Window.WindowState = WindowState.Normal;
        }
        Window.Visibility = Visibility.Visible;
    }



    /// <summary>
    /// 
    /// </summary>
    public static bool ApplicationClosing { get; set; } = false;
    /// <summary>
    /// 
    /// </summary>
    private int Index { get; set; }
    /// <summary>
    /// 
    /// </summary>
    private bool IsBinary { get; set; }
    /// <summary>
    /// 密钥
    /// </summary>
    private string SecretKey { get; set; }


    /// <summary>
    /// 配置类
    /// </summary>
    public Configs Configs { get; set; }
    /// <summary>
    /// 登录配置类
    /// </summary>
    public LoginConfigs LoginConfigs { get; set; }
    /// <summary>
    /// 
    /// </summary>
    public ICommand CMD { get; set; }
    /// <summary>
    /// 标签数据集
    /// </summary>
    private Dictionary<RadioButton, Tab> RadioKeys { get; set; }
    /// <summary>
    /// 菜单项数据集
    /// </summary>
    private Dictionary<string, Navigate> Navigation { get; set; }
    /// <summary>
    /// 侧边栏区域（对象）
    /// </summary>
    public StackPanel Panel { get; set; }
    /// <summary>
    /// 标签栏（对象）
    /// </summary>
    public StackPanel Tabs { get; set; }
    /// <summary>
    /// 
    /// </summary>
    public RadioButton SelectedTab { get; set; }
    /// <summary>
    /// 
    /// </summary>
    public Canvas Canvas { get; set; }
    /// <summary>
    /// 登录帐号
    /// </summary>
    public LoginEntity LoginEntity { get; set; }




    /// <summary>
    /// 
    /// </summary>
    public int CanvasLeft {
        get {
            return this.GetValue(x => x.CanvasLeft);
        }
        set {
            this.SetValue(x => x.CanvasLeft, value);
        }
    }
    /// <summary>
    /// 侧边导航栏最小宽度
    /// </summary>
    public double Min {
        get {
            return this.GetValue(x => x.Min);
        }
        set {
            this.SetValue(x => x.Min, value);
        }
    }
    /// <summary>
    /// 侧边导航栏宽度
    /// </summary>
    public GridLength Size {
        get {
            return this.GetValue(x => x.Size);
        }
        set {
            this.SetValue(x => x.Size, value);
        }
    }
    /// <summary>
    /// 
    /// </summary>
    public Visibility Expansion {
        get {
            return this.GetValue(x => x.Expansion);
        }
        set {
            this.SetValue(x => x.Expansion, value);
        }
    }
    /// <summary>
    /// 当前页面
    /// </summary>
    public Page CurrentPage {
        get {
            return this.GetValue(x => x.CurrentPage);
        }
        set {
            this.SetValue(x => x.CurrentPage, value);
        }
    }
    /// <summary>
    /// 登录帐号
    /// </summary>
    public string LoginName {
        get {
            return this.GetValue(x => x.LoginName);
        }
        set {
            this.SetValue(x => x.LoginName, value);
        }
    }
    /// <summary>
    /// 是否自动登录
    /// </summary>
    public bool IsAutoLogon {
        get {
            return this.GetValue(x => x.IsAutoLogon);
        }
        set {
            this.SetValue(x => x.IsAutoLogon, value);
        }
    }
    /// <summary>
    /// 是否关闭时隐藏到系统托盘
    /// </summary>
    public bool IsCloseMinTray {
        get {
            return this.GetValue(x => x.IsCloseMinTray);
        }
        set {
            this.SetValue(x => x.IsCloseMinTray, value);
        }
    }
    /// <summary>
    /// 消息数量
    /// </summary>
    public int MessageNumber {
        get {
            return this.GetValue(x => x.MessageNumber);
        }
        set {
            this.SetValue(x => x.MessageNumber, value);
        }
    }


}
